/********************************
 * ETK - Easy ToolKit
 * Copyright (C) 2007-2008 Ekinoks (scv.ekinoks@gmail.com)
 * All rights reserved.
 *
 *    This file is part of ETK.
 *
 *    Foobar is free software; you can redistribute it and/or modify
 *    it under the terms of the GNU General Public License as published by
 *    the Free Software Foundation; either version 2 of the License, or
 *    (at your option) any later version.
 *
 *    Foobar is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *    GNU General Public License for more details.
 *
 *    You should have received a copy of the GNU General Public License
 *    along with Foobar; if not, write to the Free Software
 *    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 ***********************************************************************************/

#include "../CallBack/CallBacks/CallBacks.h"
#include "../CallBack/CallBackI/CallBackT/CallBackT.h"

#include "../Event/EventButton/EventButton.h"
#include "../Event/EventScroll/EventScroll.h"
#include "../Event/EventMotion/EventMotion.h"
#include "../Event/EventKey/EventKey.h"

namespace etk
{
    // //////////////////////////////////////////////
    // //////////////// EVENTS /////////////////////
    // ////////////////////////////////////////////

    template <class F>
    CallBack * Widget::toDeleted(F f)
    {
        return new CallBackT<Event>(this, EVENT_DELETE, f);
    }

    template <class F>
    CallBack * Widget::toButtonEvent(F f, ShutterButtonModel shutter, StateModel stateModel)
    {
        CallBack *cb;
        CallBackT<EventButton> *cb1=NULL;
        CallBackT<EventButton> *cb2=NULL;
        CallBacks *cbs;

        if( shutter.isPressEvent() )
        {
            cb1 = new CallBackT<EventButton>(this, EVENT_BUTTON_PRESS, f );
            cb1->setFilter( boost::bind( EventButton::filterButtonEvent, _1, shutter, stateModel ) );
        }

        if( shutter.isReleaseEvent() )
        {
            cb2 = new CallBackT<EventButton>(this, EVENT_BUTTON_RELEASE, f );
            cb2->setFilter( boost::bind( EventButton::filterButtonEvent, _1, shutter, stateModel ) );
        }

        if( (cb1!=NULL) && (cb2!=NULL) )
        {
            cbs = new CallBacks();
            cbs->add(cb1);
            cbs->add(cb2);

            cb = cbs;
        }else
        {
            cb = ((cb1!=NULL) ? cb1 : cb2);
        }

        return cb;
    }

    template <class F>
    CallBack * Widget::toScrolled(F f, ShutterScrollModel shutter, StateModel stateModel)
    {
        CallBackT<EventScroll> *cb = new CallBackT<EventScroll>(this, EVENT_SCROLL, f);
        cb->setFilter( boost::bind( EventScroll::filterScrollEvent, _1, shutter, stateModel ) );

        return cb;
    }


    template <class F>
    CallBack * Widget::toMotionNotify(F f, StateModel stateModel)
    {
        CallBackT<EventMotion> *cb = new CallBackT<EventMotion>(this, EVENT_MOTION_NOTIFY, f);
        cb->setFilter( boost::bind( EventMotion::filterMotionEvent, _1, stateModel ) );

        return cb;
    }

    template <class F>
    CallBack * Widget::toKeyPressed(F f, ShutterKeyModel shutterKeyModel, StateModel stateModel)
    {
        CallBackT<EventKey> *cb = new CallBackT<EventKey>(this, EVENT_KEY_PRESS, f);

        cb->setFilter( boost::bind( EventKey::filterKeyEvent, _1, shutterKeyModel, stateModel) );

        return cb;
    }

    template <class F>
    CallBack * Widget::toKeyReleased(F f, ShutterKeyModel shutterKeyModel, StateModel stateModel)
    {
        CallBackT<EventKey> *cb = new CallBackT<EventKey>(this, EVENT_KEY_RELEASE, f);

        cb->setFilter( boost::bind( EventKey::filterKeyEvent, _1, shutterKeyModel, stateModel) );

        return cb;
    }

    template <class F>
    CallBack * Widget::toFocusIn(F f)
    {
        return new CallBackT<Event>(this, EVENT_FOCUS_IN, f);
    }

    template <class F>
    CallBack * Widget::toFocusOut(F f)
    {
        return new CallBackT<Event>(this, EVENT_FOCUS_OUT, f);
    }

    // /////////////// FIN EVENTS //////////////////

}


